//============================================================================
// Name        : robak-ncurses-scr.cpp
// Author      : jabko
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C, Ansi-style
//============================================================================

#include <menu.h>
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include <form.h>
#include <unistd.h>
#include "robak.h"
#include "game-printer.h"
#include "ServerSideSynchronizer.h"
#include "ClientSideSynchronizer.h"
#include "udp-server/UdpServer.h"

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define CTRLD 	4
#define SERVER_ROBAK_MODE "s"
#define CLIENT_ROBAK_MODE "k"

char *choices[] =
	{ CONNECT_WITH_SERVER, CREATE_SERVER, EXIT_NAME, (char *) NULL, };

void print_in_middle(
		     WINDOW *win,
		     int starty,
		     int startx,
		     int width,
		     char *string,
		     chtype color);

static void _run_selected_gametype(const char * param, AppData *data);

static void _create_form_ip(AppData *data);

static void _finish(int sig);

void server_test()
{

}

int udp_server_test(AppData * data)
{

	ServerSideSynchronizer * syn= ServerSideSynchronizer::getInstance();
	syn->setAppData(data);

	//rejestracja
	if ( 0 != syn->processPlayersRegistration() )
	{
		printf("Rejestracja nie powiodla sie - wychodze...");
		return 1;
	}

	sleep(1);

	syn->startGame();
	syn->startThreads();

	exit(EXIT_SUCCESS);

	return 0;
}

int udp_client_test(AppData * data)
{

	ClientSideSynchronizer * synchronizer =
			ClientSideSynchronizer::getInstance();
	synchronizer->setAppData(data);
	
	synchronizer->setPlayerNumber(1);
	gp_inform_on_middle(data, STRING_WAITING_FOR_PLAYERS);

	if (true == synchronizer->connectToServer() )
	{
		gp_inform_on_middle(data, STRING_SUCCESS_CONNECT);
	}
	else
	{
		gp_inform_on_middle(data, STRING_ERROR_CANT_CONNECT);
		return -1;
	}

	gp_inform_on_middle(data, "CZEKAM NA START GRY");
	synchronizer->waitToStart();
	synchronizer->startThreads();
	
	return 0;
}
int main(int argc, char **argv)
{

	AppData * data = (AppData *) calloc(1, sizeof(AppData));
	data->client_mode = 1;
	/*
	 if (argc - 1> 0)
	 {
	 int param_number = 1;
	 printf("ARGV[%d]=%s\n", param_number, argv[param_number]);
	 if (0 == strcmp(argv[param_number], SERVER_ROBAK_MODE ))
	 {
	 printf("Server...\n");
	 }
	 udp_server_test(data);

	 }
	 else
	 {
	 printf("Klient....\n");
	 }
	 */

	/* server_test(); */
	int n_choices, i;

	/* Initialize curses */
	initscr();
	start_color();
	cbreak();
	noecho();
	keypad(stdscr, TRUE);
	init_pair(1, COLOR_RED, COLOR_BLACK);
	init_pair(2, COLOR_YELLOW, COLOR_BLACK);
	init_pair(3, COLOR_GREEN, COLOR_BLACK);
	init_pair(4, COLOR_BLUE, COLOR_BLACK);
	init_pair(5, COLOR_WHITE, COLOR_BLACK);
	init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
	init_pair(7, COLOR_CYAN, COLOR_BLACK);
	init_pair(8, COLOR_YELLOW, COLOR_BLUE);
	init_pair(9, COLOR_YELLOW, COLOR_BLUE);
	init_pair(10, COLOR_WHITE, COLOR_BLUE);

	/* Create items */
	n_choices = ARRAY_SIZE(choices);
	data->menu_items = (ITEM **) calloc(n_choices, sizeof(ITEM *));

	for (i = 0; i < n_choices; ++i)
		data->menu_items[i] = new_item(choices[i], NULL);

	/* Crate menu */
	data->main_menu = new_menu((ITEM **) data->menu_items);

	/* Create the window to be associated with the menu */
	data->main_win = newwin(CONSOLE_Y_RES, CONSOLE_X_RES, 0, 0);
	keypad(data->main_win, TRUE);

	rk_show_main_menu(data);

	endwin();
}

void rk_show_main_menu(AppData *data)
{
	/* Create items */

	int c;
	ITEM *cur_item;

	/* Set main window and sub window */
	set_menu_win(data->main_menu, data->main_win);
	set_menu_sub(data->main_menu, derwin(data->main_win, 6, 38, 3, 1));

	/* Set menu mark to the string " * " */
	set_menu_mark(data->main_menu, " * ");

	/* Print a border around the main window and print a title */
	box(data->main_win, 0, 0);
	print_in_middle(data->main_win, 1, 0, 40, MENU_NAME, COLOR_PAIR(1));
	mvwaddch(data->main_win, 2, 0, ACS_LTEE);
	mvwhline(data->main_win, 2, 1, ACS_HLINE, 38);
	mvwaddch(data->main_win, 2, 39, ACS_RTEE);
	refresh();

	/* Post the menu */
	post_menu(data->main_menu);
	wrefresh(data->main_win);

	while ((c = wgetch(data->main_win)) !=KEY_F(1))
	{
		switch (c)
		{
		case KEY_DOWN:
			menu_driver(data->main_menu, REQ_DOWN_ITEM);
			break;
		case KEY_UP:
			menu_driver(data->main_menu, REQ_UP_ITEM);
			break;
		case REAL_ENTER_CODE: /* Enter */
			cur_item = current_item(data->main_menu);
			move(LINES - 2, 0);
			clrtoeol();
			/* running funx to determine correct action type*/
			_run_selected_gametype(item_name(cur_item), data);

			refresh();
			// pos_menu_cursor(data->main_menu);
			break;
		}
		wrefresh(data->main_win);
	}

}

void rk_hide_main_menu(AppData *data)
{
	unpost_menu(data->main_menu);
}

void rk_execute_connection(AppData *data, char * ip, char * player_name)
{
	rk_hide_main_ip_form(data);
	wclear(data->main_win);
	print_in_middle(data->main_win, 1, 0, 40, ip, COLOR_PAIR(1));

	//unpost_form(data->main_form);
	wrefresh(data->main_win);
	sleep(2);
	rk_show_main_ip_form(data);
	wrefresh(data->main_win);
}

void print_in_middle(
		     WINDOW *win,
		     int starty,
		     int startx,
		     int width,
		     char *string,
		     chtype color)
{
	int length, x, y;
	float temp;

	if (win == NULL)
		win = stdscr;
	getyx(win, y, x);
	if (startx != 0)
		x = startx;
	if (starty != 0)
		y = starty;
	if (width == 0)
		width = 80;

	length = strlen(string);
	temp = (width - length) / 2;
	x = startx + (int) temp;
	wattron(win, color);
	mvwprintw(win, y, x, "%s", string);
	wattroff(win, color);
	refresh();
}

static void _run_selected_gametype(const char * param, AppData *data)
{

	if (0 == strcmp(param, CONNECT_WITH_SERVER))
	{
		mvprintw(LINES - 2, 0, "Lacze sie z serwerem\n");
		//_create_form_ip(data);
		rk_hide_main_menu(data);//ukrywam okienko
		data->client_mode = 1;//tryb klienta
		udp_client_test(data);

	}
	else if (0 == strcmp(param, CREATE_SERVER))
	{
		mvprintw(LINES - 2, 0, "Tworze nowy serwer\n");
		rk_hide_main_menu(data);//ukrywam okienko
		data->client_mode = 0;//tryb servera
		udp_server_test(data);
		//gp_do_test_gaming(data);

	}
	else
	{
		mvprintw(LINES - 2, 0, "QUIT");
		_finish(0);
	}

}

void rk_show_main_ip_form(AppData *data)
{
	post_form(data->main_form);
}

void rk_hide_main_ip_form(AppData *data)
{
	unpost_form(data->main_form);
}

static void _create_form_ip(AppData *data)
{

	FIELD *field[3];

	int ch;
	char * player_ip= NULL;
	char* player_name= NULL;

	/* Initialize few color pairs */
#if 0
	init_pair(1, COLOR_WHITE, COLOR_BLUE);
	init_pair(2, COLOR_WHITE, COLOR_BLUE);
#endif
	/* Initialize the fields */
	field[0] = new_field(1, 10, 4, 18, 0, 0);
	field[1] = new_field(1, 10, 6, 18, 0, 0);
	field[2] = NULL;

	/* Set field options */
	set_field_fore(field[0], COLOR_PAIR(9));/* Put the field with blue background */
	set_field_back(field[0], COLOR_PAIR(10));/* and white foreground (characters */

	set_field_fore(field[1], COLOR_PAIR(9));/* Put the field with blue background */
	set_field_back(field[1], COLOR_PAIR(10));/* and white foreground (characters */
	/* are printed in white         */
	field_opts_off(field[0], O_AUTOSKIP); /* Don't go to next field when this */
	/* Field is filled up           */
	set_field_back(field[1], A_UNDERLINE);
	field_opts_off(field[1], O_AUTOSKIP);

	/* Create the form and post it */
	data->main_form = new_form(field);
	post_form(data->main_form);
	refresh();

	set_current_field(data->main_form, field[0]); /* Set focus to the colored field */
	mvprintw(4, 10, "IP:");
	mvprintw(6, 10, "IMIE");
	mvprintw(LINES - 2, 0,
			"Use UP, DOWN arrow keys to switch between fields");
	refresh();

	/* Loop through to get user requests */
	while ((ch = getch()) != KEY_F(2))
	{
		mvprintw(LINES - 2, 0, "Pressed key code is: %d|", ch);
		switch (ch)
		{
		case KEY_DOWN:
			/* Go to next field */
			form_driver(data->main_form, REQ_NEXT_FIELD);
			/* Go to the end of the present buffer */
			/* Leaves nicely at the last character */
			form_driver(data->main_form, REQ_END_LINE);
			break;
		case KEY_UP:
			/* Go to previous field */
			form_driver(data->main_form, REQ_PREV_FIELD);
			form_driver(data->main_form, REQ_END_LINE);
			break;
		case REAL_ENTER_CODE:
			form_driver(data->main_form, REQ_NEXT_FIELD);
			/* Go to the end of the present buffer */
			/* Leaves nicely at the last character */
			form_driver(data->main_form, REQ_END_LINE);
			player_ip = strdup(field_buffer(field[0], 0));
			player_name = strdup(field_buffer(field[1], 0));

			mvprintw(LINES - 2, 0, "text z entry: %s",
					field_buffer(field[0], 0));

			rk_execute_connection(data, player_ip, player_name);

			break;
		case KEY_BACKSPACE:
			form_driver(data->main_form, REQ_CLR_FIELD);
			break;
		default:
			/* If this is a normal character, it gets */
			/* Printed                                */
			form_driver(data->main_form, ch);

			break;
		}
	}

	/* Un post form and free the memory */
	unpost_form(data->main_form);
	free_form(data->main_form);
	free_field(field[0]);
	free_field(field[1]);

	endwin();
	rk_show_main_menu(data);
}

static void _finish(int sig)
{
	endwin();

	/* do your non-curses wrapup here */

	exit(0);
}

